package jmetal.metaheuristics.dnsgaii;

import java.util.HashMap;

import jmetal.core.Algorithm;
import jmetal.core.Operator;
import jmetal.core.Problem;
import jmetal.core.SolutionSet;
import jmetal.metaheuristics.nsgaII.NSGAII;
import jmetal.operators.crossover.CrossoverFactory;
import jmetal.operators.mutation.MutationFactory;
import jmetal.operators.selection.SelectionFactory;
import jmetal.problems.CarSideImpact;
import jmetal.util.JMException;

public class Exp_Car {
	
	private final static int MAX_GENETATION = 2000;
	private final static String OUTDIRECT = "output_data/nsga2/car_impact" ;
	public static void main(String[] args) throws JMException, ClassNotFoundException {
		
		Problem problem = new CarSideImpact();
		
		Algorithm algorithm = getAlgorithm(problem);
		
		for(int i = 0;i<30;i++){
			long initTime = System.currentTimeMillis();
			SolutionSet population = algorithm.execute();
			long estimatedTime = System.currentTimeMillis() - initTime;
			System.out.println("Total execution time: " + estimatedTime + "ms");
			System.out.println("Write to "+ OUTDIRECT + "/FUN" + i + ".tsv");
			population.printObjectivesToFile(OUTDIRECT + "/FUN_" + i + ".tsv");
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Algorithm getAlgorithm(Problem problem) throws JMException {
		Algorithm algorithm;
		Operator crossover;
		Operator mutation;
		Operator selection;
		HashMap parameters;
		algorithm = new NSGAII(problem);
		
		algorithm.setInputParameter("populationSize", 210);
		algorithm.setInputParameter("maxEvaluations", 210 * MAX_GENETATION);

		// Mutation and Crossover for Real codification
		parameters = new HashMap();
		parameters.put("probability", 1.0);
		parameters.put("distributionIndex", 30.0);
		crossover = CrossoverFactory.getCrossoverOperator("SBXCrossover", parameters);

		parameters = new HashMap();
		parameters.put("probability", 1.0 / problem.getNumberOfVariables());
		parameters.put("distributionIndex", 20.0);
		mutation = MutationFactory.getMutationOperator("PolynomialMutation", parameters);

		// Selection Operator
		parameters = null;
		selection = SelectionFactory.getSelectionOperator("BinaryTournamentDirFitness", parameters);

		// Add the operators to the algorithm
		algorithm.addOperator("crossover", crossover);
		algorithm.addOperator("mutation", mutation);
		algorithm.addOperator("selection", selection);

		// if it is WFG this will be true
		algorithm.setInputParameter("normalization", true);
		return algorithm;
	}
}
